#include "../StdInc.h"
#include "FemasDataBaseHelper.h"
#include "../Primitive/femas/FemasTradeApi.h"
#include "../Primitive/femas/FemasMarketDataApi.h"
#include "DataBase.h"
#include "../trade/ExecutionReportProcess.h"

namespace GSTrader
{
	namespace TradeService
	{
		CFemasDataBaseHelper::CFemasDataBaseHelper(CDataBase* pDataBase) : CDatabaseHelperBase(pDataBase)
		{
		}

		CFemasDataBaseHelper::~CFemasDataBaseHelper()
		{
		}

		CMsg* CFemasDataBaseHelper::UpdateMarkDataLoginInfo(CFemasMarketDataApi* pMarketDataApi, CUstpFtdcRspUserLoginField* pField)
		{
			if (pField != NULL)
			{
				string strInvestorID = pMarketDataApi->m_pConnectionInfo->m_strInvestorID;
				string strBrokerID = pMarketDataApi->m_pConnectionInfo->GetBrokerID();

				MakeDataBaseMarketDataMsg(msgMarketDataConnected, CAccountData, CAccountDataTable);

				pTheData->m_nClientType		= ptFemas;
				pTheData->m_nProviderId		= pMarketDataApi->m_nProviderId;
				pTheData->m_tradingDay		= pField->TradingDay;
				pTheData->m_strBrokerID		= strBrokerID;
				pTheData->m_strInvestorID	= strInvestorID;
				pTheData->m_strUserID		= strInvestorID;
				pTheData->m_nApiData			= (int)pField;
				pTheData->m_nApiType			= pMarketDataApi->m_nApiType;

				pTheData->m_pConnectionInfo		= pMarketDataApi->m_pConnectionInfo;

				if (UpdateLoginInfo(pMarketDataApi, pDataDef))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateTradeLoginInfo(CFemasTradeApi* pTradeApi, CUstpFtdcRspUserLoginField* pField)
		{
			if (pField != NULL)
			{
				MakeDataBaseTradeMsg(rspTradeLogin, CAccountData, CAccountDataTable);

				pTheData->m_nClientType = ptFemas;
				pTheData->m_nProviderId	= pTradeApi->m_nProviderId;
				pTheData->m_tradingDay	= pField->TradingDay;
				pTheData->m_strBrokerID = pField->BrokerID;
				pTheData->m_strInvestorID = pField->UserID;
				pTheData->m_strUserID	= pField->UserID;
				pTheData->m_nApiData		= (int)pTradeApi;
				pTheData->m_nApiType		= pTradeApi->m_nApiType;
				pTheData->m_strLogintime = pField->LoginTime;

				pTheData->m_pConnectionInfo = pTradeApi->m_pConnectionInfo;

				if (UpdateLoginInfo(pTradeApi, pDataDef))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}
			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateInstrument(CFemasTradeApi* pTradeApi, CUstpFtdcRspInstrumentField* pInstrument, bool bAttach, bool bDetach)
		{
			if (pInstrument)
			{
				MakeDataBaseTradeMsg(rspInstrument, CAccountInstrument, CAccountInstrumentTable);
				CInstrument ins;
				m_femasConvert.ConvertInstrument(pInstrument, &ins);

				if (UpdateInstrumentData(pTradeApi, pDataDef, &ins, bAttach, bDetach))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}
			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdatePosition(CFemasTradeApi* pTradeApi, CUstpFtdcRspInvestorPositionField* pInvestorPosition, bool bAttach,
		                                           bool bDetach)
		{
			if (pInvestorPosition)
			{
				MakeDataBaseTradeMsg(rspPosition, CPosition, CPositionTable);

				pTheData->m_nProviderId = pTradeApi->m_nProviderId;
				m_femasConvert.ConvertPosition(pInvestorPosition, pTheData);

				if (UpdatePositionData(pTradeApi, pDataDef, bAttach, bDetach, true))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateOrder(CFemasTradeApi* pTradeApi, CUstpFtdcOrderField* pOrder, bool bAttach, bool bDetach)
		{
			if (pOrder && strlen(pOrder->InstrumentID) > 0)
			{
				MakeDataBaseTradeMsg(rspOrder, COrder, COrderTable);

				pTheData->m_nProviderId = pTradeApi->m_nProviderId;
				m_femasConvert.ConvertOrder(pOrder, pTheData);

				if (UpdateOrderData(pTradeApi, pDataDef, bAttach, bDetach))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateTrade(CFemasTradeApi* pTradeApi, CUstpFtdcTradeField* pTrade, bool bAttach, bool bDetach)
		{
			if (pTrade)
			{
				MakeDataBaseTradeMsg(rspTrade, CTrade, CTradeTable);

				pTheData->m_nProviderId = pTradeApi->m_nProviderId;
				m_femasConvert.ConvertTrade(pTrade, pTheData);

				if (UpdateTradeData(pTradeApi, pDataDef, bAttach, bDetach))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateTradingAccount(CFemasTradeApi* pTradeApi, CUstpFtdcRspInvestorAccountField* pTradingAccount)
		{
			CDatabaseAttach dbAttach(m_pDataBase);

			if (pTradingAccount && strlen(pTradingAccount->AccountID) > 0)
			{
				MakeDataBaseTradeMsg(rspTradingAccount, CTradingAccount, CTradingAccountTable);

				pTheData->m_nProviderId = pTradeApi->m_nProviderId;
				m_femasConvert.ConvertTradingAccount(pTradingAccount, pTheData);

				if (UpdateTradingAccountData(pTradeApi, pDataDef))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateErrorMsg(CDataApi* pTradeApi, CUstpFtdcRspInfoField* pRspInfo)
		{
			CDatabaseAttach dbAttach(m_pDataBase);
			if (pRspInfo && pRspInfo->ErrorID != 0)
			{
				MakeDataBaseTradeMsg(rspError, CErrorMsg, CErrorMsgTable);

				pTheData->m_nErrorID	= pRspInfo->ErrorID;
				pTheData->m_nProviderId	= pTradeApi->m_nProviderId;
				pTheData->m_strErrorMsg	= pRspInfo->ErrorMsg;
				pTheData->m_nApiType	= pTradeApi->m_nApiType;
				pTheData->m_nType		= pTradeApi->m_nPlatformType;
				insert(*pDataDef);
				return pMsg;
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::UpdateExchangeStatus(CFemasTradeApi* pTradeApi, CUstpFtdcInstrumentStatusField* pInstrumentStatus)
		{
			CDatabaseAttach attach(m_pDataBase);

			if (pInstrumentStatus)
			{
				MakeDataBaseTradeMsg(msgOnExchangeStatus, CExchangeStatus, CExchangeStatusTable);
				pTheData->m_nProviderId = pTradeApi->m_nProviderId;
				m_femasConvert.ConvertExchangeStatus(pInstrumentStatus, pTheData);

				if (UpdateExchangeStatusData(pTradeApi, pDataDef))
				{
					return pMsg;
				}
				else
				{
					delete pMsg;
				}
			}

			return NULL;
		}

		CMsg* CFemasDataBaseHelper::OnRtnTrade(CFemasTradeApi* pTradeApi, CUstpFtdcTradeField* pTrade)
		{
			CTradeTable tradeDef;
			CTrade* pTheTrade = &tradeDef;
			m_femasConvert.ConvertTrade(pTrade, pTheTrade);
			pTheTrade->m_nProviderId = pTradeApi->m_nProviderId;
			return CDatabaseHelperBase::OnRtnTrade(pTradeApi, &tradeDef);
		}

		CMsg* CFemasDataBaseHelper::OnRtnOrder(CFemasTradeApi* pTradeApi, CUstpFtdcOrderField* pOrder)
		{
			COrderTable orderDef;
			COrder* pTheOrder = (COrder*)&orderDef;
			m_femasConvert.ConvertOrder(pOrder, pTheOrder);
			orderDef.m_nProviderId = pTradeApi->m_nProviderId;
			return CDatabaseHelperBase::OnRtnOrder(pTradeApi, &orderDef);
		}

		CMsg* CFemasDataBaseHelper::OrderInsertError(CFemasTradeApi* pTradeApi, CUstpFtdcInputOrderField* pInputOrder)
		{
			return NULL;
		}

		bool CFemasDataBaseHelper::GetOrder(CTradeApi* pTradeApi, COrderTable* input, OrderCursor& output)
		{
			return false;
		}

		bool CFemasDataBaseHelper::GetInputOrder(OrderCursor& orderCursor, InputOrderCursor& output)
		{
			dbQuery dbQry;
			dbQry = "m_nProviderId = ", orderCursor->m_nProviderId, " and m_strOrigOrdId =", orderCursor->m_strOrigOrdId;

			if (output.select(dbQry) > 0)
				return true;
			else
				return false;
		}

		CMsg* CFemasDataBaseHelper::UpdateMarketData(CMarketDataApi* pMarketDataApi, CUstpFtdcDepthMarketDataField* pDepthMarketData)
		{
			CDatabaseAttach attach(m_pDataBase);

			if (pMarketDataApi == NULL || pDepthMarketData == NULL)
				return NULL;

			MakeObjectMsg(msgOnNewQuoteData, CDepthMarketData);
			m_femasConvert.ConvertMarketData(pDepthMarketData, pObject);
			pObject->m_nLastUpdateProviderId = pMarketDataApi->m_nProviderId;

			if (UpdateDepthMarketData(pMarketDataApi, pObject))
			{
				return pMsg;
			}
			else
			{
				_delete(pMsg)
				return NULL;
			}
		}
	}
}